home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / programming / arexx / eqfiles / eqfiles.rexx < prev    next >
OS/2 REXX Batch file  |  1999-06-14  |  13KB  |  440 lines

  1. /* $VER: EqFiles.rexx 2.2 (30.05.99)
  2. */
  3.  
  4.  
  5. /* Filenames of external programs */
  6. /*
  7. cmp='HD0:OTHER/C/Cmp'
  8. */
  9. /* If the routine does not find external program(s), uncomment the line(s) above and insert your path(s) */
  10.  
  11.  
  12. /* Initialization */
  13. address command
  14. curdir=pragma('D')
  15. if right(curdir,1)=':' ^ right(curdir,1)='/' then curpath=curdir
  16. else curpath=curdir||'/'
  17. call open('STDERR','NIL:','write')
  18. 'Delete >NIL: T:EqFiles_#? FORCE'
  19. signal on break_c
  20.  
  21.  
  22. /* Parsing routine */
  23. say ' pParsing input string...F'
  24. parse arg instring
  25. if instring=='?' then signal template
  26. do i=1 to 10
  27.    quote1=pos('"',instring)
  28.    select
  29.       when quote1=0 then parse var instring arg.i remainder
  30.       when quote1=1 then do
  31.          quote2=pos('"',instring,2)
  32.          select
  33.             when quote2=0 then signal error1
  34.             when quote2=2 then do
  35.                if substr(instring,3,1)~=' ' then signal error2
  36.                parse var instring arg.i remainder
  37.                end
  38.             otherwise do
  39.                if substr(instring,quote2+1,1)~=' ' then signal error2
  40.                parse var instring '"'arg.i'"' remainder
  41.                end
  42.             end
  43.          end
  44.       otherwise do
  45.          if substr(instring,quote1-1,1)~=' ' then signal error2
  46.          parse var instring arg.i remainder
  47.          end
  48.       end
  49.    instring=strip(substr(remainder,2),'L')
  50.    end
  51.  
  52.  
  53. /* Input check routine */
  54. optdir1=''
  55. optdir2=''
  56. optall=''
  57. optdel=''
  58. optndl=''
  59. optfil=''
  60. opticn=''
  61. optthr=''
  62. inpat=''
  63. expat=''
  64. optpat=''
  65. threshold=0
  66. do i=1 to 10
  67.    option=upper(arg.i)
  68.    select
  69.       when option=='' then leave
  70.       when option='ALL' then do
  71.          optall=option||' '
  72.          arg.i=''
  73.          end
  74.       when option='DELETE' then do
  75.          optdel=option||' '
  76.          arg.i=''
  77.          end
  78.       when option='NODL' then do
  79.          optndl=option||' '
  80.          arg.i=''
  81.          end
  82.       when option='FILES' then do
  83.          optfil=option||' '
  84.          arg.i=''
  85.          end
  86.       when option='ICONS' then do
  87.          opticn=option||' '
  88.          arg.i=''
  89.          end
  90.       when left(option,5)='SIZE>' then do
  91.          optthr=option
  92.          arg.i=''
  93.          end
  94.       when left(option,6)='INPAT=' then do
  95.          inpat=substr(arg.i,7)
  96.          arg.i=''
  97.          end
  98.       when left(option,6)='EXPAT=' then do
  99.          expat=substr(arg.i,7)
  100.          arg.i=''
  101.          end
  102.       when optdir1=='' then do
  103.          optdir1=arg.i
  104.          arg.i=''
  105.          end
  106.       when optdir2=='' then do
  107.          optdir2=arg.i
  108.          arg.i=''
  109.          end
  110.       otherwise nop
  111.       end
  112.    end
  113. select
  114.    when optdir1=='' then signal error3
  115.    when optdir1=='""' then dir1=curpath
  116.    otherwise do
  117.       'Dir >NIL: "'optdir1'" Dirs'
  118.       if RC=20 then signal error4
  119.       colon=pos(':',optdir1)
  120.       if colon=0 then dir1=curpath||optdir1
  121.       else do
  122.          expdir1=pragma('D',pragma('D',left(optdir1,colon)))
  123.          if right(expdir1,1)~=':' then expdir1=expdir1||'/'
  124.          dir1=expdir1||substr(optdir1,colon+1)
  125.          end
  126.       end
  127.    end
  128. select
  129.    when optdir2=='' then dir2=dir1
  130.    when optdir2=='""' then dir2=curpath
  131.    otherwise do
  132.       'Dir >NIL: "'optdir2'" Dirs'
  133.       if RC=20 then signal error5
  134.       colon=pos(':',optdir2)
  135.       if colon=0 then dir2=curpath||optdir2
  136.       else do
  137.          expdir2=pragma('D',pragma('D',left(optdir2,colon)))
  138.          if right(expdir2,1)~=':' then expdir2=expdir2||'/'
  139.          dir2=expdir2||substr(optdir2,colon+1)
  140.          end
  141.       end
  142.    end
  143. do i=1 to 10
  144.    if arg.i~=='' then signal error6
  145.    end
  146. if optthr~='' then do
  147.    threshold=right(optthr,length(optthr)-5)
  148.    if datatype(threshold,W)~=1 | threshold<0 then signal error7
  149.    optthr=optthr||' '
  150.    end
  151.  
  152.  
  153. /* Pattern expansion routine */
  154. nopat1=0
  155. nopat2=0
  156. dir1max=1
  157. dir2max=1
  158. dircheck=0
  159. if exists(dir1)=1 then do
  160.    dir1=pragma('D',pragma('D',dir1))
  161.    if right(dir1,1)~=':' & right(dir1,1)~='/' then dir1=dir1||'/'
  162.    dir1.1=dir1
  163.    nopat1=1
  164.    end
  165. else do
  166.    say 'Expanding patterns...  F'
  167.    if right(dir1,1)~='/' then dir1=dir1||'/'
  168.    'Dir >T:EqFiles_DList1 "'dir1'" DIRS'
  169.    call open('in','T:EqFiles_DList1','read')
  170.    if seek('in',0,'E')=0 then signal error8
  171.    call seek('in',0,'B')
  172.    j=1
  173.    do i=1
  174.       line=readln('in')
  175.       if line='' then leave
  176.       dir1.i=strip(left(line,length(line)-6))
  177.       if right(dir1.i,1)~=':' & right(dir1.i,1)~='/' then dir1.i=dir1.i||'/'
  178.       if i>1 & dir1.j~==dir1.i then do
  179.          j=j+1
  180.          if j~=i then dir1.j=dir1.i
  181.          end
  182.       end
  183.    dir1max=j
  184.    call close('in')
  185.    end
  186. if exists(dir2)=1 then do
  187.    dir2=pragma('D',pragma('D',dir2))
  188.    if right(dir2,1)~=':' & right(dir2,1)~='/' then dir2=dir2||'/'
  189.    dir2.1=dir2
  190.    nopat2=1
  191.    end
  192. else if upper(dir1)~==upper(dir2) then do
  193.    say 'Expanding patterns...  F'
  194.    if right(dir2,1)~='/' then dir2=dir2||'/'
  195.    'Dir >T:EqFiles_DList2 "'dir2'" DIRS'
  196.    call open('in','T:EqFiles_DList2','read')
  197.    if seek('in',0,'E')=0 then signal error8
  198.    call seek('in',0,'B')
  199.    j=1
  200.    do i=1
  201.       line=readln('in')
  202.       if line='' then leave
  203.       dir2.i=strip(left(line,length(line)-6))
  204.       if right(dir2.i,1)~=':' & right(dir2.i,1)~='/' then dir2.i=dir2.i||'/'
  205.       if i>1 & dir2.j~==dir2.i then do
  206.          j=j+1
  207.          if j~=i then dir2.j=dir2.i
  208.          end
  209.       end
  210.    dir2max=j
  211.    call close('in')
  212.    end
  213. if dir1~==dir2 then do
  214.    if dir1max~=dir2max then dircheck=1
  215.    else do i=1 to dir1max
  216.       if dir1.i~==dir2.i then dircheck=1 ; leave
  217.       end
  218.    end
  219. if inpat='' then inpat='#?'
  220. select
  221.    when expat='' & opticn='' then expat='~(#?.INFO)'
  222.    when expat='' & opticn='ICONS ' then expat='#?'
  223.    when expat~='' & opticn='' then expat='~((#?.INFO)|('expat'))'
  224.    when expat~='' & opticn='ICONS ' then expat='~('expat')'
  225.    end
  226. optpat='PAT="~(~('expat')|~('inpat'))"'
  227.  
  228.  
  229. /* Data acquisition and preprocessing routine */
  230. if dircheck=0 then comment='Scanning "'dir1
  231. else comment='Scanning "'dir1'" and "'dir2
  232. optfull=optall|| optdel||optndl||optfil||opticn||optthr||optpat
  233. if optfull='' then say comment'"'
  234. else say comment'" with option(s) 'optfull''
  235. say 'Acquiring data...    F'
  236. do i=1 to dir1max
  237.    'List >>T:EqFiles_FList "'dir1.i'" lformat="%8l 'dircheck' %p%n*"'dir1.i'" FILES 'optall optpat
  238.    if nopat1~=1 & optndl~='NODL' then say'  <dir1> 'dir1.i'  ...scanned'
  239.    end
  240. call open('in','T:EqFiles_FList','read')
  241. flen=seek('in',0,'E')
  242. if flen=0 then signal error8
  243. say 'Preprocessing data...  F'
  244. call seek('in',0,'B')
  245. fnum1=-1
  246. do until EOF('in')
  247.    call readln('in')
  248.    fnum1=fnum1+1
  249.    end
  250. call close('in')
  251. if dircheck=1 then do
  252.    say 'Acquiring data...    F'
  253.    do i=1 to dir2max
  254.       'List >>T:EqFiles_FList "'dir2.i'" lformat="%8l 2 %p%n*"'dir2.i'" FILES 'optall optpat
  255.    if nopat2~=1 & optndl~='NODL' then say '  <dir2> 'dir2.i'  ...scanned'
  256.       end
  257.    call open('in','T:EqFiles_FList','read')
  258.    if flen=seek('in',0,'E') then signal error9
  259.    say 'Preprocessing data...  F'
  260.    call seek('in',flen+1,'B')
  261.    fnum2=-1
  262.    do until EOF('in')
  263.       call readln('in')
  264.       fnum2=fnum2+1
  265.       end
  266.    call close('in')
  267.    end
  268. 'Sort T:EqFiles_FList TO T:EqFiles_FList CASE'
  269.  
  270.  
  271. /* Main routine */
  272. pos=0
  273. index=0
  274. items=0
  275. call open('in','T:EqFiles_FList','read')
  276. call open('out','T:EqFiles_Result','write')
  277. do forever
  278.    line1=readln('in')
  279.    if line1='' | index=fnum1 then leave
  280.    if substr(line1,10,1)='2' then iterate
  281.    else do
  282.       index=index+1
  283.       say 'Processing file 'index' of 'fnum1' in <dir1>F'
  284.       end
  285.    len1=left(line1,8)
  286.    if len1<=threshold then iterate
  287.    curpos=seek('in',0,'C')
  288.    do forever
  289.       line2=readln('in')
  290.       if line2='' then leave
  291.       if substr(line2,10,1)='1' then iterate
  292.       len2=left(line2,8)
  293.       if len2=len1 then do
  294.          fname1=substr(line1,12,pos('"',line1)-12)
  295.          fname2=substr(line2,12,pos('"',line2)-12)
  296.          if fname1~==fname2 & exists(fname1)=1 & exists(fname2)=1 then do
  297.             dpath1=substr(line1,pos('"',line1)+1)
  298.             dpath2=substr(line2,pos('"',line2)+1)
  299.             select
  300.                when abbrev(dpath1,dpath2)=1 then ineq=fname1<fname2
  301.                when abbrev(dpath2,dpath1)=1 then ineq=fname1>fname2
  302.                otherwise ineq=1
  303.                end
  304.             if ineq=1 then do
  305.                cmp '"'fname1'" "'fname2'" DUMP 0 CHECKD >NIL:'
  306.                if RC=0 then do
  307.                   if optdel='DELETE ' then do
  308.                      call writeln('out',fname1' == 'fname2'')
  309.                      'Delete "'fname2'" FORCE QUIET'
  310.                      end
  311.                   else call writeln('out',fname1' == 'fname2)
  312.                   items=items+1
  313.                   end
  314.                end
  315.             end
  316.          end
  317.       else leave
  318.       end
  319.    call seek('in',curpos,'B')
  320.    end
  321. say ' p                                  F'
  322. call close('in')
  323. call close('out')
  324.  
  325.  
  326. /* Output routine */
  327. if fnum1=1 then plural1=''
  328. else plural1='s'
  329. if fnum2=1 then plural2=''
  330. else plural2='s'
  331. if items=1 then do
  332.    plural=''
  333.    verb='has'
  334.    end
  335. else do
  336.    plural='s'
  337.    verb='have'
  338.    end
  339. if items~=0 then do
  340.    'Sort T:EqFiles_Result To T:EqFiles_Result'
  341.    'Type T:EqFiles_Result'
  342.    if dir1==dir2 then say ''fnum1' file'plural1' found in <dir1>.            '
  343.    else say ''fnum1' file'plural1' found in <dir1>; 'fnum2' file'plural2' found in <dir2>.'
  344.    if optdel='DELETE ' then say ''items' pair'plural' of equal files detected. Highlighted file'plural verb' been deleted.'
  345.    else say ''items' pair'plural' of equal files detected.'
  346.    end
  347. else do
  348.    if dir1==dir2 then say ''fnum1' file'plural1' found in <dir1>.            '
  349.    else say ''fnum1' file'plural1' found in <dir1>; 'fnum2' file'plural2' found in <dir2>.'
  350.    say 'No equal files detected.'
  351.    end
  352. if optfil~='FILES ' then 'Delete T:EqFiles_#? QUIET'
  353. else 'Delete T:EqFiles_FList QUIET'
  354. exit
  355.  
  356.  
  357. break_c:
  358. say 'EUser break!E p'
  359. call close('in')
  360. call close('out')
  361. 'Delete T:EqFiles_#? QUIET'
  362. exit
  363.  
  364.  
  365. error1:
  366. say 'EIllegal number of  "  delimiters!E p'
  367. exit
  368.  
  369.  
  370. error2:
  371. say 'EIllegal use of  "  delimiters!E p'
  372. exit
  373.  
  374.  
  375. error3:
  376. say 'EYou must specify at least one directory!E p'
  377. exit
  378.  
  379.  
  380. error4:
  381. say 'FE<dir1> "'optdir1'" not found: erroneous directory name/pattern!E p'
  382. exit
  383.  
  384.  
  385. error5:
  386. say 'FE<dir2> "'optdir2'" not found: erroneous directory name/pattern!E p'
  387. exit
  388.  
  389.  
  390. error6:
  391. say 'EOption "'arg.i'" not allowed!E p'
  392. exit
  393.  
  394.  
  395. error7:
  396. say 'EWrong SIZE specification!E p'
  397. exit
  398.  
  399.  
  400. error8:
  401. say 'ENo (allowed) files in directory "'dir1'" !E p'
  402. call close('in')
  403. 'Delete T:EqFiles_#? QUIET'
  404. exit
  405.  
  406.  
  407. error9:
  408. say 'ENo (allowed) files in directory "'dir2'" !E p'
  409. call close('in')
  410. 'Delete T:EqFiles_#? QUIET'
  411. exit
  412.  
  413.  
  414. template:
  415. say 'EEqFiles V2.2 by Fulvio Peruggi - May 30, 1999E'
  416. say 'Usage: [rx] EqFiles[.rexx] [<dir1>] [<dir2>] [ALL] [DELETE] [NODL] [FILES]'
  417. say '                                      [SIZE>x] [INPAT=y] [EXPAT=z] [ICONS]'
  418. say 'EEqFiles scans all files in directories <dir1> and <dir2>, compares each'
  419. say '  file in <dir1> with all files in <dir2> having the same size, and lists'
  420. say '  all pairs of equal files.'
  421. say '<dir1> and/or <dir2> can be explicit directory names or legal AmigaDOS'
  422. say '  patterns. If <dir2> is not specified, <dir2>=<dir1> by default.'
  423. say 'Command operations act on the files in all subdirectories of the given'
  424. say '  directories if the optional parameter ALL is specified.'
  425. say 'Equal files found in <dir2> are deleted and notified if the optional'
  426. say '  parameter DELETE is specified.'
  427. say 'A list of all the directories recovered by the patterns is automatically'
  428. say '  typed. This can be prevented if the optional parameter NODL is specified.'
  429. say 'All directories scanned and all pairs of equal files detected are stored in'
  430. say '  the files T:EqFiles_DList1T:EqFiles_DList2, and T:EqFiles_Result. The'
  431. say '  optional parameter FILES prevents their deletion on exit.'
  432. say 'The optional parameter SIZE>x, where x is a positive integer, prevents'
  433. say '  comparisons between files with size lower than, or equal to, x.'
  434. say 'The optional parameters INPAT=y and/or EXPAT=z, where y and z must be legal'
  435. say '  AmigaDOS patterns, can be used to select and/or reject all files whose'
  436. say '  filenames match the patterns.'
  437. say 'By default, icons are never compared unless the optional parameter ICONS'
  438. say '  is specified.E p'
  439. exit
  440.